package com.github.common.util.pool;

import com.github.common.util.lang.AssertUtil;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ExecutorServicesFactory {

    /**
     * 获取ExecutorService
     *
     * @param config           ThreadPoolConfig
     * @param rejectHandler
     * @return ExecutorService
     */
    public static ExecutorService build(ThreadPoolConfig config, ThreadFactory factory, RejectedExecutionHandler rejectHandler) {
        //core-size需要配置;
        Integer queueSize = config.getQueueSize();
        Integer coreSize = config.getCoreSize();
        Integer maxSize = config.getMaxSize();
        Integer keepAliveSec = config.getKeepAliveSec();

        AssertUtil.notNullOrEmpty(queueSize, "queueSize");
        AssertUtil.notNullOrEmpty(coreSize, "coreSize");
        AssertUtil.notNullOrEmpty(maxSize, "maxSize");
        AssertUtil.notNullOrEmpty(keepAliveSec, "keepAliveSec");

        AssertUtil.assertPositive(coreSize, "pool-core-size");
        AssertUtil.assertNotSmallerThan(maxSize, "pool-max-size", coreSize);
        AssertUtil.assertPositive(keepAliveSec, "keep-alive-sec");
        BlockingQueue<Runnable> queue = queueSize == 0 ? new SynchronousQueue<>() : new ArrayBlockingQueue<>(queueSize);
        return new ThreadPoolExecutor(coreSize, maxSize, keepAliveSec, TimeUnit.SECONDS, queue, factory,rejectHandler);
    }

}
